
package com.nvlled.route;

import java.util.concurrent.ConcurrentHashMap;
import java.util.*;
import java.net.*;

public class AddressTable {
    //Map<String, String> table;
    Map<String, SocketAddress> addressLookup;
    Map<SocketAddress, String> nameLookup;

    public AddressTable() {
        addressLookup = new ConcurrentHashMap<String, SocketAddress>();
        nameLookup = new ConcurrentHashMap<SocketAddress, String>();
        try {
            InetAddress local = InetAddress.getLocalHost();
            store("default", new InetSocketAddress(local, 80));
        } catch (Exception e) { }
    }

    public AddressTable(SocketAddress defaultAdresss) {
        // TODO: Use a thread-safe map
        addressLookup = new HashMap<String, SocketAddress>();
        nameLookup = new HashMap<SocketAddress, String>();
        store("default", defaultAdresss);
    }

    public void clear() {
        nameLookup.clear();
        addressLookup.clear();
        assert(nameLookup.size() == 0);
        assert(addressLookup.size() == 0);
    }

    public int size() {
        return nameLookup.size();
    }

    public Set<String> getNames() {
        return new HashSet(addressLookup.keySet());
    }

    public Set<SocketAddress> getAddresses() {
        return nameLookup.keySet();
    }


    // I realized this is a broken implementation
    // but fixing it breaks a lot of things 
    public void store(String name, SocketAddress sock) {
        assert(!nameLookup.containsKey(sock));
        addressLookup.put(name, sock);
        nameLookup.put(sock, name);
    }

    public void removeName(String name) {
        SocketAddress address = addressLookup.remove(name);
        nameLookup.remove(address);
    }

    public void removeNameOnly(String name) {
        addressLookup.remove(name);
    }

    public void removeAddress(SocketAddress address) {
        String name = nameLookup.remove(address);
        addressLookup.remove(name);
    }

    public SocketAddress getAddress(String name) {
        return addressLookup.get(name);
    }

    public String getName(SocketAddress address) {
        return nameLookup.get(address);
    }
}

